"""
OS Install api
"""


import json
import time
from concurrent.futures import ThreadPoolExecutor

from .command import raw_command, integrated_command
from .argument import build_args
from redfishtoollib import main

THREAD_POOL = ThreadPoolExecutor(max_workers=2)


# install os with iso injected to virtual media
# params:
# {'iso': 'nfs://10.1.1.100/data/nfs/iso/CentOS7.iso', 'host': '10.1.1.100', 'username': 'root account', 'password': 'root password'}
def install_os_with_nfs_shared_iso():
    args = build_args()
    try:
        params = json.loads(args.d)
    except ValueError:
        params = {}
    cmd = raw_command(args, 'GET', '/redfish/v1/Managers', None)
    if params.get('log', ''):
        with open(params.get('log', ''), 'a+') as f:
            f.write('[dispatch commands]\nquery managers: ' + str(cmd) + '\n')
    res = main(cmd)
    if params.get('log', ''):
        with open(params.get('log', ''), 'a+') as f:
            f.write('get result:\n' + res + '\n')
    try:
        urls = json.loads(res)
    except ValueError:
        urls = {}
    if len(urls.get('Members', [])) > 0:
        base_url = urls.get('Members', [])[0].get('@odata.id')
        cmd = raw_command(args, 'GET', base_url + '/VirtualMedia', None)
        if params.get('log', ''):
            with open(params.get('log', ''), 'a+') as f:
                f.write('query all virtual medias: ' + str(cmd) + '\n')
        res = main(cmd)
        if params.get('log', ''):
            with open(params.get('log', ''), 'a+') as f:
                f.write('get result:\n' + res + '\n')
        try:
            vms = json.loads(res)
        except ValueError:
            vms = {}
        urls = list(filter(lambda x: 'CD' in x['@odata.id'], vms['Members']))
        if len(urls) > 0:
            eject_url = urls[0]['@odata.id'] + '/Actions/VirtualMedia.EjectMedia'
            cmd = raw_command(args, 'POST', eject_url, '{}')
            if params.get('log', ''):
                with open(params.get('log', ''), 'a+') as f:
                    f.write('eject first virtual media: ' + str(cmd) + '\n')
            res = main(cmd)
            if params.get('log', ''):
                with open(params.get('log', ''), 'a+') as f:
                    f.write('get result:\n' + res + '\n')
            try:
                eject_res = json.loads(res)
            except ValueError:
                eject_res = {}
            if ('Success' in eject_res.get('Status', '')) or ('Success' in eject_res.get('error', {}).get('message')):
                inject_url = urls[0]['@odata.id'] + '/Actions/VirtualMedia.InsertMedia'
                cmd = raw_command(args, 'POST', inject_url, '{"Image": "%s"}' % params.get('iso', ''))
                if params.get('log', ''):
                    with open(params.get('log', ''), 'a+') as f:
                        f.write('inject first virtual media: ' + str(cmd) + '\n')
                res = main(cmd)
                if params.get('log', ''):
                    with open(params.get('log', ''), 'a+') as f:
                        f.write('get result:\n' + res + '\n')
                try:
                    inject_res = json.loads(res)
                except ValueError:
                    inject_res = {}
                if ('Success' in inject_res.get('Status', '')) or (inject_res.get('error', {}).get('message')):
                    cmd = integrated_command(args, 'Systems', '--all', 'setBootOverride', 'Once', 'Cd')
                    if params.get('log', ''):
                        with open(params.get('log', ''), 'a+') as f:
                            f.write('modify boot option to "Once" "Cd" "UEFI" mode: ' + str(cmd) + '\n')
                    res = main(cmd)
                    if params.get('log', ''):
                        with open(params.get('log', ''), 'a+') as f:
                            f.write('get result:\n' + res + '\n')
                    try:
                        boot = json.loads(res)
                    except ValueError:
                        boot = {}
                    if boot.get('Boot', {}).get('BootSourceOverrideMode') == 'UEFI' and boot.get('Boot', {}).get('BootSourceOverrideEnabled') == 'Once' and boot.get('Boot', {}).get('BootSourceOverrideTarget') == 'Cd':
                        cmd = raw_command(args, 'GET', '/redfish/v1/Systems', None)
                        if params.get('log', ''):
                            with open(params.get('log', ''), 'a+') as f:
                                f.write('query systems: ' + str(cmd) + '\n')
                        res = main(cmd)
                        if params.get('log', ''):
                            with open(params.get('log', ''), 'a+') as f:
                                f.write('get result:\n' + res + '\n')
                        try:
                            urls = json.loads(res)
                        except ValueError:
                            urls = {}
                        if len(urls.get('Members', [])) > 0:
                            base_url = urls.get('Members', [])[0].get('@odata.id')
                            cmd = raw_command(args, 'GET', base_url, None)
                            if params.get('log', ''):
                                with open(params.get('log', ''), 'a+') as f:
                                    f.write('query system members: ' + str(cmd) + '\n')
                            res = main(cmd)
                            if params.get('log', ''):
                                with open(params.get('log', ''), 'a+') as f:
                                    f.write('get result:\n' + res + '\n')
                            try:
                                state = json.loads(res)
                            except ValueError:
                                state = {}
                            if state.get('PowerState') == 'On':
                                cmd = raw_command(args, 'POST', base_url + '/Actions/ComputerSystem.Reset', '{"ResetType": "ForceRestart"}')
                                res = main(cmd)
                            elif state.get('PowerState') == 'Off':
                                cmd = raw_command(args, 'POST', base_url + '/Actions/ComputerSystem.Reset', '{"ResetType": "On"}')
                                res = main(cmd)
                            else:
                                cmd = raw_command(args, 'POST', base_url + '/Actions/ComputerSystem.Reset', '{"ResetType": "ForceRestart"}')
                                res = main(cmd)
                            if params.get('log', ''):
                                with open(params.get('log', ''), 'a+') as f:
                                    f.write('restart server: ' + str(cmd) + '\n')
                                    f.write('get result:\n' + res + '\n')
                            try:
                                restart = json.loads(res)
                            except ValueError:
                                restart = {}
                            if ('SUCCESS' in restart.get('error', {}).get('message', '').upper()) or ('SUCCESS' in restart.get('error', {}).get('Message', '').upper()) or ('SUCCESS' in restart.get('error', {}).get('@Message.ExtendedInfo', {})[0].get('Message', '').upper()):
                                print('Success')
                        if params.get('log', ''):
                            with open(params.get('log', ''), 'a+') as f:
                                f.write('try tracing install logs\n')
                        THREAD_POOL.submit(trace_install_process, args, params)


def trace_install_process(args, params):
    if params.get('log', ''):
        with open(params.get('log', ''), 'a+') as f:
            f.write('[install process]\n')
    i = 0
    while i < 10:
        i = i + 1
        time.sleep(1)
        with open(params.get('log', ''), 'a+') as f:
            f.write('this is fake process: %d%%, do not believe it\n' % (i * 10))
    with open(params.get('log', ''), 'a+') as f:
        f.write('[os install completed]')
